package com.andatsoft.laisim.view;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import org.htmlcleaner.BaseTokenImpl;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.TextView;

import com.andatsoft.laisim.R;
import com.andatsoft.laisim.activity.EditLyricsActivity;
import com.andatsoft.laisim.activity.EditTagInfoActivity;
import com.andatsoft.laisim.activity.MainActivity;
import com.andatsoft.laisim.adapter.MainPagerSongListAdapter;
import com.andatsoft.laisim.db.DataBaseAccess;
import com.andatsoft.laisim.dialog.LyricsGettingDialog;
import com.andatsoft.laisim.entity.Playlist;
import com.andatsoft.laisim.entity.Song;
import com.andatsoft.laisim.service.PlayerService;
import com.andatsoft.laisim.theme.Theme;
import com.andatsoft.laisim.theme.ThemeManager;
import com.andatsoft.laisim.utils.Common;
import com.andatsoft.laisim.utils.Utils;
import com.andatsoft.laisim.view.SlimProgressBar.SlimProgressClicked;
import com.nineoldandroids.view.ViewHelper;

public class MainSongListFragment extends Fragment {

	private ListView mListView;
	private Playlist mPlaylist;
	private View mLayoutBg;
	private MainPagerSongListAdapter mAdapter;
	private Point mToolBoxPosition;
	private int mSongId;
	private float mAlpha;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.pager_main_song_list, container,
				false);
		mListView = (ListView) view
				.findViewById(R.id.list_pager_main_song_list);
		mListView.setScrollingCacheEnabled(false);
		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int pos,
					long id) {
				if (!getPlayerService().isFading()) {
					getMainActivity().getPlayerService().play(pos);
				}

			}
		});
		mListView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent e) {
				if (e.getAction() == MotionEvent.ACTION_DOWN) {
					if (mToolBoxPosition == null)
						mToolBoxPosition = new Point();
					mToolBoxPosition.x = (int) e.getX();
					mToolBoxPosition.y = (int) e.getY();
				}
				return false;
			}
		});

		mListView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int pos, long arg3) {
				mSongId = getMainActivity().getPlaylist().getSong(pos).getId();
				Rect r = new Rect();
				mListView.getGlobalVisibleRect(r);

				getMainActivity().doLaisimAnimation(mToolBoxPosition.x,
						mToolBoxPosition.y + r.top);

				showToolBox(mSongId, pos);
				return true;
			}
		});
		mLayoutBg = view.findViewById(R.id.layout_main_pager_song_list);
		return view;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		if (mPlaylist == null || mPlaylist.getCount() <= 0)
			mPlaylist = ((MainActivity) getActivity()).getPlaylist();
		if (mAdapter == null)
			mAdapter = new MainPagerSongListAdapter(getActivity(),
					mPlaylist.getSongList());
		mAdapter.setDataChanged(mPlaylist.getSongList());
		mListView.setAdapter(mAdapter);
	}

	@Override
	public void onResume() {
		super.onResume();
		mAdapter.notifyThemeChanged();
		applyTheme();
	}

	@SuppressLint("NewApi")
	private void applyTheme() {
		Theme theme = ThemeManager.getSelectedTheme();
		mAlpha = ThemeManager.getSelectedTheme().getMPLBackgroundAlpha();
		setAlpha(mLayoutBg, mAlpha);
		mLayoutBg.setBackgroundColor(theme.getMainBackgroundColor());
		if (Utils.androidOs > Common.ANDROID_OS_GINGERBREAD)
			mListView.setSelector(createListSelector());
	}

	@SuppressLint("NewApi")
	private StateListDrawable createListSelector() {
		ColorDrawable clrPress = new ColorDrawable();
		clrPress.setColor(ThemeManager.getSelectedTheme()
				.getMPLSelectedTitleColor());

		StateListDrawable states = new StateListDrawable();
		states.addState(new int[] { android.R.attr.state_selected }, null);
		states.addState(new int[] { android.R.attr.state_pressed }, clrPress);

		return states;
	}

	private void setBgColor(View v) {
		v.setBackgroundColor(ThemeManager.getSelectedTheme()
				.getDialogBackgroundColor() | 0xff000000);
	}

	public void updateAdapter() {
		if (getActivity() == null)
			return;
		mPlaylist = ((MainActivity) getActivity()).getPlaylist();
		mAdapter.setDataChanged(mPlaylist.getSongList());

		// //mAdapter.notifyDataSetChanged();
		// mAdapter = new MainPagerSongListAdapter(getActivity(),
		// mPlaylist.getSongList());
		// mListView.setAdapter(mAdapter);

	}

	public void updateAdapter(int id) {
		// mPlaylist = ((MainActivity) getActivity()).getPlaylist();
		// mAdapter = new MainPagerSongListAdapter(getActivity(),
		// mPlaylist.getSongList());
		mPlaylist = ((MainActivity) getActivity()).getPlaylist();
		mAdapter.setSelectedItem(getSongIndexById(id));
		mAdapter.setDataChanged(mPlaylist.getSongList());

		// mListView.setAdapter(mAdapter);
	}

	public void scrollToCurrentSongIndex(int index) {
		mListView.setSelection(index);
	}

	private int getSongIndexById(int id) {
		for (int i = 0; i < mPlaylist.getSongList().size(); i++) {
			if (id == mPlaylist.getSong(i).getId())
				return i;
		}
		return -1;
	}

	public Fragment getInstance() {
		return this;
	}

	private PlayerService getPlayerService() {
		return ((MainActivity) getActivity()).getPlayerService();
	}

	public void setPlaylist(Playlist pl) {
		this.mPlaylist = pl;
	}

	public ListView getListView() {
		return mListView;
	}

	public MainPagerSongListAdapter getAdapter() {
		return mAdapter;
	}

	public void updateListView() {
		final int index = getPlayerService().getCurrentSongIndex();
		// MainPagerSongListAdapter ad = ((MainPagerSongListAdapter) mListView
		// .getAdapter());
		mAdapter.setSelectedItem(index);
		mAdapter.notifyDataSetChanged();
	}

	// public void reUpdateAdapter() {
	// mAdapter = new MainPagerSongListAdapter(getActivity(),
	// mPlaylist.getSongList());
	// mListView.setAdapter(mAdapter);
	// }

	public MainActivity getMainActivity() {
		return (MainActivity) getActivity();
	}

	@SuppressLint("NewApi")
	protected void setAlpha(View view, float alpha) {
		if (Utils.androidOs > Common.ANDROID_OS_GINGERBREAD) {
			view.setAlpha(alpha);
		} else {
			ViewHelper.setAlpha(view, alpha);
		}
	}

	private void showToolBox(final int songId, final int index) {
		final Toolbox toolBox = getMainActivity().getToolBox();

		if (toolBox == null)
			return;
		toolBox.setContentLayout(R.layout.tool_box_pager_list_song);
		toolBox.show();

		final TextView btnEditTags = (TextView) toolBox
				.findViewById(R.id.tv_song_list_edit_tags);
		setBgColor(btnEditTags);
		btnEditTags.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		btnEditTags.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnEditTags.setEnabled(false);
					editTags(songId);
					toolBox.close();
					getMainActivity().setNeedUpdateUI(true);
					break;
				}
				return true;
			}
		});

		final TextView btnUpdateLyrics = (TextView) toolBox
				.findViewById(R.id.tv_song_list_update);
		setBgColor(btnUpdateLyrics);
		btnUpdateLyrics.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		btnUpdateLyrics.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnUpdateLyrics.setEnabled(false);
					updateLyrics(index);
					toolBox.close();
					getMainActivity().setNeedUpdateUI(true);
					break;
				}
				return true;
			}
		});

		final TextView btnEditLyrics = (TextView) toolBox
				.findViewById(R.id.tv_song_list_edit_lyrics);
		if (!isSongHasLyrics(songId)) {
			btnEditLyrics.setVisibility(View.GONE);
		} else {
			setBgColor(btnEditLyrics);
			btnEditLyrics.setTextColor(ThemeManager.getSelectedTheme()
					.getNormalTextColor());
			btnEditLyrics.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						setAlpha(v, 0.5f);
						break;
					case MotionEvent.ACTION_UP:
						setAlpha(v, 1.0f);
						getMainActivity().doLaisimAnimation(v);
						btnEditLyrics.setEnabled(false);
						editLyrics(songId);
						toolBox.close();
						getMainActivity().setNeedUpdateUI(true);
						break;
					}
					return true;
				}
			});
		}
		final TextView btnDel = (TextView) toolBox
				.findViewById(R.id.tv_song_list_remove);
		btnDel.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		setBgColor(btnDel);
		btnDel.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnDel.setEnabled(false);
					removeSong(index, songId);
					toolBox.close();
					getMainActivity().setNeedUpdateUI(true);
					break;
				}
				return true;
			}
		});
		final TextView btnUpdateTags = (TextView) toolBox
				.findViewById(R.id.tv_song_list_update_tags);
		btnUpdateTags.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		setBgColor(btnUpdateTags);
		btnUpdateTags.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnUpdateTags.setEnabled(false);
					// getMainActivity().setAsRingtone(songId);
					updateTags(mSongId);
					toolBox.close();
					break;
				}
				return true;
			}
		});
		final TextView btnSend = (TextView) toolBox
				.findViewById(R.id.tv_song_list_send);
		btnSend.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		setBgColor(btnSend);
		btnSend.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnSend.setEnabled(false);
					getMainActivity().sendFile(songId);
					toolBox.close();
					break;
				}
				return true;
			}
		});
		final TextView btnDetail = (TextView) toolBox
				.findViewById(R.id.tv_song_list_detail);
		btnDetail.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		setBgColor(btnDetail);
		btnDetail.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnDetail.setEnabled(false);
					getMainActivity().goToDetail(songId);
					toolBox.close();
					break;
				}
				return true;
			}
		});
		setBgColor(toolBox
				.findViewById(R.id.layout_song_list_transparent_background));
		final TextView tvBg = (TextView) toolBox
				.findViewById(R.id.tv_song_list_transparent_background);

		tvBg.setTextColor(ThemeManager.getSelectedTheme().getNormalTextColor());
		final SlimProgressBar progressBg = (SlimProgressBar) toolBox
				.findViewById(R.id.progress_song_list_transparent_background);
		progressBg.setBackgroundWidth(6f);
		progressBg.setProgressWidth(4f);
		progressBg.setMax(100);
		progressBg.setProgress((int) (mAlpha * 100));
		progressBg.setOnSlimClicked(new SlimProgressClicked() {

			@Override
			public void onClick(int newProgress) {
				mAlpha = ((float) newProgress) / 100;
				setAlpha(mLayoutBg, mAlpha);
			}
		});

		toolBox.getContent().setPadding(0, mToolBoxPosition.y, 0, 0);

	}

	private void updateTags(int songId) {
		new UpdatetagsTask().execute(songId);
	}
	
	private void editTags(int songId) {
		Intent i = new Intent(getActivity(), EditTagInfoActivity.class);
		i.putExtra(MainActivity.INTENT_DATA_MAIN_EDIT_TAGS_SONG_ID, songId);
		getActivity().startActivityForResult(i,
				Common.REQUEST_CODE_FOR_EDIT_TAGS);
	}

	private void editLyrics(int songId) {
		Intent i = new Intent(getActivity(), EditLyricsActivity.class);
		i.putExtra(Common.SONG_ID_INTENT, songId);
		String lyrics = getMainActivity().loadSongLyrics(songId);
		i.putExtra(Common.SONG_LYRICS_INTENT, lyrics);
		startActivity(i);
	}

	private void updateLyrics(int index) {
		Intent i = new Intent(getActivity(), LyricsGettingDialog.class);
		i.putExtra(Common.SONG_TITLE_INTENT, ((MainActivity) getActivity())
				.getPlaylist().getSong(index).getTitle());
		startActivityForResult(i, Common.REQUEST_CODE_FOR_LIST_DIALOG);
	}

	private void removeSong(final int index, final int songId) {

		String delMess = getString(R.string.message_box_delete_song);
		OnTouchListener okEvent = new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (!getMainActivity().isCanClickMessageBox()) {
					return true;
				}
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					int currentId = getMainActivity().getCurrentSongId();

					getMainActivity().removeSong(index);
					int newIndex = index;
					// the deleted song is the playing song
					if (songId == currentId) {
						if (newIndex >= mPlaylist.getCount() - 1)
							newIndex = mPlaylist.getCount() - 1;
						if (mPlaylist.getCount() > 0) {
							if (getMainActivity().getPlayerService()
									.isPlaying()) {
								getMainActivity().getPlayerService().play(
										newIndex);
							} else {
								getMainActivity().getPlayerService()
										.updateSongWhenRemove(newIndex);
							}
						} else {
							getMainActivity().getPlayerService().resetLaisim(
									false);
						}
					} else {
						// re update playing song index
						newIndex = getSongIndexById(currentId);
					}
					getMainActivity().setCurrentSongIndex(newIndex);
					mAdapter.setSelectedItem(newIndex);
					mAdapter.notifyDataSetChanged();

					DataBaseAccess db = DataBaseAccess
							.getInstance(getActivity().getApplicationContext());
					db.savePlayingSong(mPlaylist.getSongList());
					db.removeSong(mSongId);
					//

					getMainActivity().updateCurrentIndex();
					cancelMessageBox();
					getMainActivity().setCanClickMessageBox(false);
					break;
				}
				return false;

			}
		};

		OnTouchListener cancelEvent = new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (!getMainActivity().isCanClickMessageBox()) {
					return true;
				}
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().setCanClickMessageBox(false);
					cancelMessageBox();
					break;
				}
				return false;
			}
		};
		showMessageBox(delMess, okEvent, cancelEvent);
	}

	private boolean isSongHasLyrics(int songId) {
		DataBaseAccess db = DataBaseAccess.getInstance(getActivity().getApplicationContext());
		boolean re = db.isSongHasLyrics(songId);
		return re;
	}

	private void cancelMessageBox() {
		getMainActivity().dismissMessageBox();
	}

	private void showMessageBox(String content, OnTouchListener okEvent,
			OnTouchListener cancelEvent) {
		getMainActivity().showMessageBox(content, okEvent, cancelEvent);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == Common.REQUEST_CODE_FOR_LIST_DIALOG) {
			if (resultCode == 0)// Cancel
			{

			} else if (resultCode == Common.RESULT_CODE_FOR_LYRICS_FRAGMENT) {
				String url = data
						.getStringExtra(Common.RESULT_INTENT_FOR_LYRICS_FRAGMENT);
				new LyricsGetterAndSaver().execute(url);
			}

		}
	}

	class UpdatetagsTask extends AsyncTask<Integer, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Integer... params) {
			int songId = params[0];
			if (songId < 0)
				return false;
			Song s = getMainActivity().getPlaylist().getSongById(mSongId);
			s.updateSongInfo(getMainActivity());
			DataBaseAccess db = DataBaseAccess.getInstance(getMainActivity());
			db.updateSong(s);
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if (result == null)
				return;
			if (result) {
				mAdapter.notifyDataSetChanged();
			}
		}
	}
	
	private String getURLId(String src) {
		String re = src.substring(src.lastIndexOf("/") + 1,
				src.lastIndexOf(".html"));
		return re;
	}

	private String editLine(String line) {
		if (line == null)
			return "";
		line = line.trim();
		if (line.equals("br")) {
			return "\n";
		}
		if (line.equals("span")) {
			return "";
		}
		return line;
	}

	class LyricsGetterAndSaver extends AsyncTask<String, Void, Integer> {

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			if (getActivity() == null)
				return;
			((MainActivity) getActivity())
					.getToast()
					.showLongMessage(
							getString(R.string.tool_box_song_list_toast_updating_lyrics));
		}

		@Override
		protected Integer doInBackground(String... params) {
			String src = params[0];
			try {
				URL url = new URL(src);
				HtmlCleaner html = new HtmlCleaner();
				CleanerProperties props = html.getProperties();
				props.setAllowHtmlInsideAttributes(true);
				props.setAllowMultiWordAttributes(true);
				props.setRecognizeUnicodeChars(true);
				props.setOmitComments(true);

				TagNode node = html.clean(url);
				String xPathExpression = "//div[@id='_lyricContainer"
						+ getURLId(src) + "']//p";

				Object[] obj = node.evaluateXPath(xPathExpression);
				if (obj == null || obj.length <= 0)
					return 0;
				TagNode lyricTag = (TagNode) obj[0];
				@SuppressWarnings("unchecked")
				List<BaseTokenImpl> content = (List<BaseTokenImpl>) lyricTag
						.getAllChildren();
				StringBuilder result = new StringBuilder();
				for (int i = 0; i < content.size(); i++) {
					String line = content.get(i).toString();
					line = editLine(line);
					// Log.d("Lyrics", line);
					result.append(line);
				}
				((MainActivity) getActivity()).updateSongLyrics(mSongId,
						result.toString());
				return 1;
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (XPatherException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return 0;
		}

		@Override
		protected void onPostExecute(Integer result) {
			if (getActivity() == null)
				return;
			if (result == 1) {
				((MainActivity) getActivity())
						.getToast()
						.showLongMessage(
								getString(R.string.tool_box_song_list_toast_updating_lyrics_ok));
			} else {
				((MainActivity) getActivity())
						.getToast()
						.showLongMessage(
								getString(R.string.tool_box_song_list_toast_updating_lyrics_failed));
			}
		}
	}

}
